﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
using cma.cimiss.client;
using cma.cimiss;
using System.Text.RegularExpressions;
using System.IO;

using NPOI.HSSF.UserModel;
using NPOI.SS.UserModel;
using NPOI.XSSF.UserModel;

namespace yubao
{
    /// <summary>
    /// MainWindow.xaml 的交互逻辑
    /// </summary>
    public partial class MainWindow : Window
    {
        string times = "00";
        string data = "";
        string datapath1 = @"M:\ecmwf_thin\2T\999\";//EC数据基本路径
        string datapath2 = "";//ec数据路径临时
        int shixiao = 0;//数据时间间隔临时值
        string stationpath = System.Environment.CurrentDirectory + @"\设置文件\站点经纬度-10进制.txt";//站点信息文本路径，当前程序文件夹下的“设置文件夹”中

        private void ComboBoxItem_Selected_0(object sender, RoutedEventArgs e)
        {
            times = "00";//选择08时时次UTC为0
        }

        private void ComboBoxItem_Selected_1(object sender, RoutedEventArgs e)
        {
            times = "12";//选择20时时次UTC为12
        }
        public MainWindow()
        {
            InitializeComponent();
            ECpath.Text = "EC全路径";
            shixiaoBox.Text = "08";
            checkEC.IsChecked = true;
            checkZD.IsChecked = true;//默认都勾选导出EC和指导预报
        }

        //双线性插值函数
        public double sxxcz(double data11, double data12, double data21, double data22, double wd1, double wd2, double jd1, double jd2, double stationJD, double stationWD)
        {
            double stationData;
            /*
             数据点的位置  d12（jd2,wd2）   d22(jd1,wd2)
                                    d(sjd,swd)
                           d11(jd2,wd1)     d21(jd1,wd1)
            */
            stationData = (data11 * (jd1 - stationJD) * (wd2 - stationWD)) / ((jd1 - jd2) * (wd2 - wd1)) + (data21 * (stationJD - jd2) * (wd2 - stationWD)) / ((jd1 - jd2) * (wd2 - wd1)) + (data12 * (jd1 - stationJD) * (stationWD - wd1)) / ((jd1 - jd2) * (wd2 - wd1)) + (data22 * (stationJD - jd2) * (stationWD - wd1)) / ((jd1 - jd2) * (wd2 - wd1));


            return stationData;
        }

        //检查指定路径下指定时间的EC数据从000至168时次的文件是否存在
        bool pathJC(string path)
        {
            bool boolPath = true;
            string path1;
            for (int i = 0; i <= 168;)
            {
                path1 = path;

                if (i < 72)
                {
                    path1 = path + i.ToString().PadLeft(3, '0');
                    boolPath = boolPath && File.Exists(path1);
                    i += 3;
                }
                else
                {
                    path1 = path + i.ToString().PadLeft(3, '0');
                    boolPath = boolPath && File.Exists(path1);
                    i += 6;
                }

            }
            return boolPath;
        }

        string MaxMin(string stationID)//根据区站号返回未来五天最高最低温度
        {
            string datapath;//ec数据完整路径

            //循环寻找每天最高最低温度，之前的变量shixiao，新变量shixiao1，shixiao1=shixiao，shixiao1变量随着循环增加，xunhuan1-xunhuan对24取余为0时，为一天
            int shixiao1 = shixiao;
            double maxTem = -999, minTem = 999;//最高温度设到最低是为了第一次循环时候可以被别的温度值替换,最低温同理
            double temDou;
            string temStr = "";
            while ((shixiao1 - shixiao) <= 120)
            {
                datapath = datapath2 + shixiao1.ToString().PadLeft(3, '0');
                string[] sStation = File.ReadAllLines(stationpath, Encoding.Default);
                double stationJD = 0, stationWD = 0;//站点的经度和纬度
                double data11, data12, data21, data22;//指定位置附近四个点的数据值
                int intJD1, intJD2, intWD1, intWD2;//指定位置数据数组中经度、纬度序号
                for (int i = 0; i < sStation.Length; i++)
                {

                    if (sStation[i].IndexOf(stationID) > -1)
                    {
                        string[] ss1 = sStation[i].Split(' ');
                        stationJD = Convert.ToDouble(ss1[2]);
                        stationWD = Convert.ToDouble(ss1[1]);
                    }
                }

                string[] sData = File.ReadAllLines(datapath, Encoding.Default);
                string[] config = sData[4].Split(' ');

                double JDGJ, WDGJ, QSJD, QSWD;//经度格距，纬度格距，起始经度，起始纬度
                JDGJ = Convert.ToDouble(config[0]);
                WDGJ = Convert.ToDouble(config[1]);
                QSJD = Convert.ToDouble(config[2]);
                QSWD = Convert.ToDouble(config[4]);

                intJD1 = (int)Math.Ceiling((stationJD - QSJD) / JDGJ);//经度个数向上取整
                intJD2 = intJD1 - 1;//经度个数向下取整
                intWD1 = (int)Math.Ceiling((stationWD - QSWD) / WDGJ);//纬度个数向上取整
                intWD2 = intWD1 - 1;//纬度个数向下取整

                /*
                数据点的位置  d12（jd2,wd2）   d22(jd1,wd2)
                                       d(sjd,swd)
                              d11(jd2,wd1)     d21(jd1,wd1)
               */

                double wd1, wd2, jd1, jd2;//数据附近四个点的经纬度
                wd1 = WDGJ * intWD1 + QSWD;
                wd2 = WDGJ * intWD2 + QSWD;
                jd1 = JDGJ * intJD1 + QSJD;
                jd2 = JDGJ * intJD2 + QSJD;

                data21 = Convert.ToDouble((sData[2 * intWD1 + 6].Split('\t'))[intJD1]);//数据从第六行开始，故加6；每行数据之间有一个空行，故纬度个数*2；
                data11 = Convert.ToDouble((sData[2 * intWD1 + 6].Split('\t'))[intJD2]);
                data22 = Convert.ToDouble((sData[2 * intWD2 + 6].Split('\t'))[intJD1]);
                data12 = Convert.ToDouble((sData[2 * intWD2 + 6].Split('\t'))[intJD2]);
                //t1.Text = datapath+'\n' +Convert.ToString(data12) + ' ' + Convert.ToString(data22) + '\n' + Convert.ToString(data11) + ' ' + Convert.ToString(data21);
                temDou = Math.Round(sxxcz(data11, data12, data21, data22, wd1, wd2, jd1, jd2, stationJD, stationWD), 1);//对附近四个点做双线性插值
                if (maxTem < temDou)//如果最高温低于本时次插值出的温度则替换为本时次
                    maxTem = temDou;
                if (minTem > temDou)//如果最低温高于本时次插值出的温度则替换为本时次
                    minTem = temDou;
                if (((shixiao1 - shixiao) != 0) && ((shixiao1 - shixiao) % 24 == 0))//如果不是000时次，则(shixiao1-shixiao)能被24整除时说明为一天过去了，则将最高与最低温度保存，然后将他们初始化为当前时次温度
                {
                    temStr += Convert.ToString(minTem) + '\t' + Convert.ToString(maxTem) + '\t';
                    maxTem = temDou;
                    minTem = temDou;
                }

                if (shixiao1 < 72)
                {
                    shixiao1 = shixiao1 + 3;
                }
                else if (shixiao1 >= 72)
                {
                    shixiao1 = shixiao1 + 6;
                }

            }
            temStr = temStr.Substring(0,temStr.Length-1);
            return temStr;
        }

        //EC预报函数
        void ECyubao()
        {
            string timeStr, riqiStr;//待查询ec的时间（08或者20时），待查询日期
            if (shixiaoBox.Text == "08")
            {
                riqiStr = System.DateTime.Now.AddDays(-1).ToString("yyMMdd");
                timeStr = "20";
                datapath2 = datapath1 + riqiStr + timeStr + ".";
                shixiao = 12;
                if (!(pathJC(datapath2)))
                {
                    shixiao = 24;
                    timeStr = "08";
                    datapath2 = datapath1 + riqiStr + timeStr + ".";
                    if (!(pathJC(datapath2)))
                    {
                        t1.Text = "抱歉，没有前两个时次的数据";
                        return;
                    }

                }
            }
            else if (shixiaoBox.Text == "20")
            {
                riqiStr = System.DateTime.Now.ToString("yyMMdd");
                timeStr = "08";
                datapath2 = datapath1 + riqiStr + timeStr + ".";
                shixiao = 12;
                if (!(pathJC(datapath2)))
                {
                    shixiao = 24;
                    timeStr = "20";
                    riqiStr = System.DateTime.Now.AddDays(-1).ToString("yyMMdd");
                    datapath2 = datapath1 + riqiStr + timeStr + ".";
                    if (!(pathJC(datapath2)))
                    {
                        t1.Text = "抱歉，没有前两个时次的数据";
                        return;
                    }

                }
            }
            ECpath.Text = datapath2;
           
            string strLinShi;
            using (StreamReader str = new StreamReader(stationpath, Encoding.Default))
            {
                while ((strLinShi = str.ReadLine()) != null)
                {
                    string[] strSZ = strLinShi.Split(' ');
                    t1.Text += strSZ[0] + '\t' + MaxMin(strSZ[0]) + '\n';//区站号+未来五天最低最高温

                }
            }
            t1.Text = t1.Text.Substring(0,t1.Text.Length-1);

            //将EC预报数据转置，便于读取
            string strEC = t1.Text;          
            string[] ec1 = strEC.Split('\n');
            string[,] ec3 = new string[ec1.Length, ec1[0].Split('\t').Length];
            for(int i = 0;i<ec1.Length;i++)
            {
                string[] ec2= ec1[i].Split('\t');
                for (int j=0;j<ec2.Length;j++)
                {
                    ec3[i, j] = ec2[j];
                }
                
            }
            t1.Text = "";
            for(int i = 0;i<ec3.GetLength(1); i++)
            {
                for(int j =0;j<ec3.GetLength(0);j++)
                {
                    t1.Text += ec3[j, i]+'\t';
                }
                t1.Text = t1.Text.Substring(0,t1.Text.Length-1);
                t1.Text += '\n';
            }
            t1.Text = t1.Text.Substring(0, t1.Text.Length - 1);
            string ECyubaopath= System.Environment.CurrentDirectory + @"\EC预报.txt";
            File.WriteAllText(ECyubaopath, t1.Text,Encoding.UTF8);
        }

        private void find_Click(object sender, RoutedEventArgs e)
        {
            t1.Text = "";
            ECyubao();
            string Times = "";
            Times = DateTime.Now.ToString("yyyyMMdd") + times + "0000";
            zhidaoyubao yubao1 = new zhidaoyubao();
            t2.Text= yubao1.yb(Times, out data);           

        }

        private void button_DC_Click(object sender, RoutedEventArgs e)
        {
            t2.Text = "";
            string excelPath = @"D:\预报表(杨泽华).xls";
            HSSFWorkbook wk = null;
            using (FileStream fs = File.Open(excelPath, FileMode.Open, FileAccess.Read, FileShare.ReadWrite))
            {
                wk = new HSSFWorkbook(fs);
                fs.Close();
            }
            ISheet sheet1 = wk.GetSheet("模板2");          
            ISheet sheet2;
            try
            {
                sheet2 = sheet1.CopySheet(DateTime.Now.ToString("yyyyMMdd") + shixiaoBox.Text);
            }
            catch(Exception ex)
            {
                sheet2 = wk.GetSheet(DateTime.Now.ToString("yyyyMMdd") + shixiaoBox.Text);
            }
            sheet1 = null;

           
            if (checkZD.IsChecked==true)
            {
                //指导预报导出至excel
                t2.Text += "指导导出";
                string ZDyubaopath = System.Environment.CurrentDirectory + @"\指导预报.txt";
                string[] ZDSZ= File.ReadAllLines(ZDyubaopath);
                
                int excelHS = 3;//指导预报从第4行开始
                for (int i = 1; i < ZDSZ.Length; i++, excelHS += 7)
                {

                    IRow row = sheet2.GetRow(excelHS);
                    string[] WDSZ = ZDSZ[i].Split('\t');
                    for(int j=0,excelLS=1;j<WDSZ.Length;j++,excelLS++)
                    {
                        ICell cell = row.GetCell(excelLS);
                        cell.SetCellValue(Convert.ToDouble(WDSZ[j]));
                        //增加读取excel ，excel行数为excelHS,列数为excelLS
                    }
                }
            }
            if(checkEC.IsChecked==true)
            {
                //EC预报导出至excel
                t2.Text += "EC导出";
                string ECyubaopath = System.Environment.CurrentDirectory + @"\EC预报.txt";
                string[] ECSZ = File.ReadAllLines(ECyubaopath);

                int excelHS = 4;//指导预报从第5行开始
                for (int i = 1; i < ECSZ.Length; i++, excelHS += 7)
                {

                    IRow row = sheet2.GetRow(excelHS);
                    string[] WDSZ = ECSZ[i].Split('\t');
                    for (int j = 0, excelLS = 1; j < WDSZ.Length; j++, excelLS++)
                    {
                        ICell cell = row.GetCell(excelLS);
                        cell.SetCellValue(Convert.ToDouble(WDSZ[j]));
                        //增加读取excel ，excel行数为excelHS,列数为excelLS
                    }
                }
            }
            else if((!(checkEC.IsChecked == true))&& (!(checkZD.IsChecked == true)))
            {
                t2.Text = "啥都不勾选，你导出个灰机？";
            }
            wk.SetActiveSheet(wk.NumberOfSheets-1);
            using (FileStream fileStream = File.Open(excelPath, FileMode.OpenOrCreate, FileAccess.ReadWrite))
            {
                wk.Write(fileStream);
                fileStream.Close();
            }
            
        }
    }

    public class zhidaoyubao
    {
        
        string stationpath = System.Environment.CurrentDirectory + @"\设置文件\站点经纬度-10进制.txt";//站点信息文本路径，当前程序文件夹下的“设置文件夹”中
        public string yb(string Times, out string data1)
        {
            /* 1. 定义client对象 */
            DataQueryClient client = new DataQueryClient();

            /* 2.   调用方法的参数定义，并赋值 */
            /*   2.1 用户名&密码 */
            String userId = "BEHT_BFHT_2131";// 
            String pwd = "YZHHGDJM";// 
            /*   2.2 接口ID */
            String interfaceId = "getSevpWefcRffcByTimeAndStaID";
            /*   2.3 接口参数，多个参数间无顺序 */
            Dictionary<String, String> params1 = new Dictionary<String, String>();
            // 必选参数
            params1.Add("dataCode", "SEVP_CHN_WEFC_RFFC"); // 资料代码
            params1.Add("elements", "Station_Name,Station_Id_C,Prod_Code,Validtime,TEM_Max_24h,TEM_Min_24h");// 检索要素：站号、产品代码、预报24小时最高、最低温度
            params1.Add("time", Times); // 检索时间
            string strLinShi,strSID="";
            using (StreamReader str = new StreamReader(stationpath, Encoding.Default))
            {
                while ((strLinShi = str.ReadLine()) != null)
                {
                    string[] strSZ = strLinShi.Split(' ');
                    strSID += strSZ[0]+',';

                }
            }
            strSID = strSID.Substring(0,strSID.Length-1);
            params1.Add("staIds", strSID);// 检索站号
            // 可选参数
            params1.Add("orderby", "Validtime:asc,Station_Id_C:asc"); // 排序：按照站号从小到大
            params1.Add("eleValueRanges", "Prod_Code:SCMOC;TEM_Max_24h:(,9999)"); // 筛选产品代码：SMOC为中央台指导产品
            /*   2.4 返回文件的格式 */
            String dataFormat = "text";
            /*   2.5 文件的本地全路径 */
            //String savePath = @"F:\Users\yzh54\Desktop\123.txt";
            /*   2.6 返回文件的描述对象 */
            RetFilesInfo retFilesInfo = new RetFilesInfo();
            StringBuilder retStr = new StringBuilder();//返回字符串

            /* 3.   调用接口 */
            try
            {
                // 初始化接口服务连接资源
                client.initResources();
                Console.WriteLine("finally initResources");
                // 调用接口
                int rst = client.callAPI_to_serializedStr(userId, pwd, interfaceId, params1, dataFormat, retStr);
                // 输出结果
                if (rst == 0)
                {   // 正常返回
                     data1 = Convert.ToString(retStr);
                    string[] YBHSJ = Regex.Split(data1, "\r\n", RegexOptions.IgnoreCase);//按行读取指导数据
                    string[] IDSZ = strSID.Split(',');
                    string strYB="";
                    for (int i =0;i<IDSZ.Length;i++)//按区站号排序
                    {
                        strYB += IDSZ[i] + '\t';
                        for(int j=2;j<(IDSZ.Length*5+2); j++)//获取每个区站的最低和最高温度，5天，因此IDSZ的长度乘以5，因为数据头两行为其他数据，故+2
                        {
                            string[] YBLSJ = YBHSJ[j].Split(' ');
                            if (YBLSJ[1]==IDSZ[i])
                            {
                                strYB += YBLSJ[5]+'\t'+YBLSJ[4] + '\t';
                            }
                        }
                        strYB = strYB.Substring(0,strYB.Length-1);
                        strYB += '\n';

                    }
                    strYB = strYB.Substring(0, strYB.Length - 1);

                    //将指导预报数据转置，便于读取
                    string[] yb1 = strYB.Split('\n');
                    string[,] yb3 = new string[yb1.Length, yb1[0].Split('\t').Length];
                    for (int i = 0; i < yb1.Length; i++)
                    {
                        string[] yb2 = yb1[i].Split('\t');
                        for (int j = 0; j < yb2.Length; j++)
                        {
                            yb3[i, j] = yb2[j];
                        }

                    }
                    strYB = "";
                    for (int i = 0; i < yb3.GetLength(1); i++)
                    {
                        for (int j = 0; j < yb3.GetLength(0); j++)
                        {
                            strYB += yb3[j, i] + '\t';
                        }
                        strYB = strYB.Substring(0, strYB.Length - 1);
                        strYB += '\n';
                    }
                    strYB = strYB.Substring(0, strYB.Length - 1);
                    string ZDyubaopath = System.Environment.CurrentDirectory + @"\指导预报.txt";
                    File.WriteAllText(ZDyubaopath, strYB, Encoding.UTF8);
                    
                    data1 = strYB;
                    return data1;

                }
                else
                {   // 异常返回
                    data1 = "error";
                    return "error";
                }
            }
            catch (Exception e)
            {
                // 异常输出
                Console.WriteLine(e.Message);
                //e.Message();
            }
            finally
            {
                // 释放接口服务连接资源
                client.destroyResources();

            }
            //Console.ReadKey();
            data1 = "";
            return "";

        }
    }
}
